
package com.casic.controller;

//import com.casic.dao.IotDeviceDao;

import cn.hutool.json.JSONUtil;
import com.alibaba.druid.support.json.JSONUtils;
import com.casic.aspect.annotation.Auth;
import com.casic.dao.*;
import com.casic.dto.ParamDTO;
import com.casic.entity.*;
import com.casic.util.JacksonMapperUtil;
import com.casic.util.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Api(tags = "数据采集接口")
@Slf4j
@RestController
@RequestMapping("/api/1.1/iot")
public class DataController {

	/**
	  * 设备的dao
	  */
	 @Autowired
     private IotDeviceDao iot_DeviceDao;

	/**
	 * 数据库操作
	 */
	 @Autowired
	 private MongoDao mongoDao;

	/**
	 * 告警配置查询
	 */
	 @Autowired
	 private WarnConfDao warnConfDao;

	/**
	 * 告警信息
	 */
	 @Autowired
	 private WarnMsgDao warnMsgDao;

	/**
	 * 实时数据采集接口
	 * @param dto
	 * @param request
	 * @return
	 */
	@ApiOperation("采集点数据采集接口")
	@Auth
	@PostMapping(value = "data_acquire",produces="application/json; charset=UTF-8")
	public R dataAcquire(@RequestBody ParamDTO dto,
									   HttpServletRequest request) {
		log.info("---------data_acquirev1.1 interface start--------");
		log.info("Parameters are as follows:");
		log.info(JacksonMapperUtil.beanToJson(dto));

		try {
			String jsonStr=JacksonMapperUtil.beanToJson(dto);
			if(jsonStr.startsWith("{")&&jsonStr.endsWith("}")) {
				log.info("----------------------数据格式正确---------------------");

				//2.校验通过存kafka
				String iot = dto.getIot();
				String equipment = dto.getEquipment();
				Long orgId = iot_DeviceDao.selectOrgIdByEquipment(equipment);
				List<Map<String, Object>> dataList = dto.getData();// 采集点数据

				HashMap<String, Object> httpArg = new HashMap<String, Object>();
				if (dataList != null && dataList.size() > 0) {
					for (Map<String, Object> map : dataList) {
						httpArg = new HashMap<String, Object>();
						httpArg.put("orgId", String.valueOf(orgId));
						httpArg.put("iot", iot);
						httpArg.put("equipment", equipment);
						httpArg.put("createTime", String.valueOf(new Date().getTime()));
						httpArg.put("k", map.get("k").toString());
						httpArg.put("v", map.get("v").toString());
						httpArg.put("t", map.get("t").toString());
						final String jsonResult = JSONUtils.toJSONString(httpArg);
						mongoDao.save(JSONUtil.toBean(JSONUtil.parseFromMap(httpArg), IotData.class));
						/**
						 * 新线程单独处理告警信息
						 */
						new Thread(new Runnable() {
							@Override
							public void run() {
								try {
									//告警信息
									warnInfo(String.valueOf(orgId),iot,equipment,map.get("k").toString(),map.get("v").toString());
								} catch (Exception e) {
									log.info("提交告警信息异常："+e.getLocalizedMessage());
								}
							}
						}).start();;

					}
				}
			}else{
				log.info("----------------------数据格式不正确---------------------");
				return R.error("数据格式错误");
			}


			log.info("---------data_acquirev1.1 interface end--------");
			return R.ok();
		} catch (NumberFormatException e) {
			e.printStackTrace();
			log.info("---------data_acquirev1.1 interface error--------");
			return R.error(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			log.info("---------data_acquirev1.1 interface error--------");
			return R.error(e.getMessage());
		}
	}



	/**
	 * 设备状态采集接口
	 * @param dto
	 * @param request
	 * @return
	 */
	@ApiOperation("状态采集接口")
	@Auth
	@PostMapping(value = "device_state_acquire",produces="application/json; charset=UTF-8")
	public R deviceStateAcquire(
			@RequestBody ParamDTO dto,
			HttpServletRequest request) {
		log.info("---------equipment_state_acquire interface start--------");
		log.info("Parameters are as follows:");
		log.info(JacksonMapperUtil.beanToJson(dto));

		try {

			// 2.校验通过存kafka
			String iot = dto.getIot();
			List<Map<String, Object>> dataList = dto.getData();// 采集点数据

			HashMap<String, Object> httpArg = new HashMap<String, Object>();
			if (dataList != null && dataList.size() > 0) {
				for (Map<String, Object> map : dataList) {
					httpArg = new HashMap<String, Object>();
					httpArg.put("iot", iot);
					httpArg.put("createTime", String.valueOf(new Date().getTime()));
					String equipment =map.get("equipment").toString();
					Long orgId = iot_DeviceDao.selectOrgIdByEquipment(equipment);
					httpArg.put("orgId", String.valueOf(orgId));
					httpArg.put("equipment", equipment);
					httpArg.put("k", "state");
					httpArg.put("v", map.get("v").toString());
					httpArg.put("t", map.get("t").toString());
					final String jsonResult = JSONUtils.toJSONString(httpArg);
					mongoDao.save(JSONUtil.toBean(JSONUtil.parseFromMap(httpArg), IotData.class));
					/**
					 * 新线程单独处理告警信息
					 */
					new Thread(new Runnable() {
						@Override
						public void run() {
							try {
								warnInfo(String.valueOf(orgId),iot,equipment,"state",map.get("v").toString());
							} catch (Exception e) {
								log.info("提交告警信息异常："+e.getLocalizedMessage());
							}
						}
					}).start();;

				}
			}
			log.info("---------equipment_state_acquire interface end--------");
			return R.ok();
		} catch (NumberFormatException e) {
//			e.printStackTrace();
			log.info("---------equipment_state_acquire interface error--------");
			return R.error(e.getMessage());
		} catch (Exception e) {
//			e.printStackTrace();
			log.info("---------equipment_state_acquire interface error--------");
			return R.error(e.getMessage());
		}
	}

	/**
	 * 存入采集点告警信息
	 */
	public void warnInfo(String orgId,String iotId,String deviceId,String keyName,String value) throws Exception{
		List<WarnConfEntity> confList=findWarnConfList(orgId,iotId,deviceId,keyName);
		if(confList!=null&&confList.size()>0){
			for (WarnConfEntity conf :confList) {
				/**
				 * 比较值是否满足条件
				 */
				Integer symbol=conf.getSymbol();
				switch (symbol){
					case 1:
						//大于
						if(Double.valueOf(value)>Double.valueOf(conf.getLimit1())){
							//采集点上传的值大于设定阀值
							saveWarnMess(conf,value,"采集点上传的值大于设定阀值："+conf.getLimit1());
						}
						break;
					case 2:
						//大于等于
						if(Double.valueOf(value)>=Double.valueOf(conf.getLimit1())){
							//采集点上传的值大于等于设定阀值
							saveWarnMess(conf,value,"采集点上传的值大于等于设定阀值："+conf.getLimit1());
						}
						break;
					case 3:
						//小于
						if(Double.valueOf(value)<Double.valueOf(conf.getLimit1())){
							//采集点上传的值小于设定阀值
							saveWarnMess(conf,value,"采集点上传的值小于设定阀值："+conf.getLimit1());
						}
						break;
					case 4:
						//小于等于
						if(Double.valueOf(value)<=Double.valueOf(conf.getLimit1())){
							//采集点上传的值小于等于设定阀值
							saveWarnMess(conf,value,"采集点上传的值小于等于设定阀值："+conf.getLimit1());
						}
						break;
					case 5:
						//等于
						if(Double.valueOf(value)==Double.valueOf(conf.getLimit1())){
							//采集点上传的值等于设定阀值
							saveWarnMess(conf,value,"采集点上传的值等于设定阀值："+conf.getLimit1());
						}
						break;
					case 6:
						//不等于
						if(Double.valueOf(value)!=Double.valueOf(conf.getLimit1())){
							//采集点上传的值不等于设定阀值
							saveWarnMess(conf,value,"采集点上传的值不等于设定阀值："+conf.getLimit1());
						}
						break;
					case 7:
						//区间
						if(Double.valueOf(value)>=Double.valueOf(conf.getLimit1())&&Double.valueOf(value)<=Double.valueOf(conf.getLimit2())){
							saveWarnMess(conf,value,"采集点上传的值在设定阀值："+ conf.getLimit1()+"  --  "+ conf.getLimit2()+"之间");
						}
						break;
				}

			}
		}

	}

	/**
	 * 保存提示消息
	 * @param conf
	 * @param warnRule
	 */
	private void saveWarnMess(WarnConfEntity conf,String v,String warnRule)  throws Exception{
		//满足大于条件
		WarnMsgEntity message=new WarnMsgEntity();
		message.setWarnid(conf.getId());
		message.setIotid(conf.getIotid());
		message.setDevid(conf.getDevid());
		message.setColpointid(conf.getColpointid());
		message.setOrgid(conf.getOrgid());
		message.setWarnrule(warnRule);
		message.setCurrentdata(v);
		message.setCurrenttime(new Date());
		message.setStatus(0);
		warnMsgDao.save(message);
	}


	/**
	 * 网关、设备、采集点的name 返回对应采集点的配置的规则
	 */
	public List<WarnConfEntity> findWarnConfList(String orgId,String iotId,String deviceId,String keyName) throws Exception{
		List<WarnConfEntity> confList=new ArrayList<>();
		Map<String,String> map=new HashMap<>();
		map.put("orgId",orgId);
		map.put("iotId",iotId);
		map.put("deviceId",deviceId);
		map.put("keyName",keyName);
		confList=warnConfDao.findByMap(map);
		return  confList;
	}

}
